﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using Common.Commands;
using fc2editor.Common;
using fc2editor.DataModel;
using fc2editor.Services;

namespace fc2editor.ViewModels
{
    public class WeaponSelectorViewModel : ViewModelBase, IWeaponSelectorViewModel
    {
        public WeaponSelectorViewModel(IWeaponService weaponService)
        {
            ViewVisibility = Visibility.Hidden;
            Weapons = weaponService.GetWeapons();

            SelectWeaponCommand = new DelegateCommand<object>(OnSelectWeaponCommand);
            CancelSelectWeaponCommand = new DelegateCommand<object>(OnCancelSelectWeaponCommand);
            KeyDownCommand = new DelegateCommand<object>(OnKeyDownCommand);
            ClearFilterCommand = new DelegateCommand<object>(OnClearFilterCommand);

            FilterText = String.Empty;
        }

        #region IWeaponSelectorViewModel Members

        public Visibility ViewVisibility
        {
            get
            {
                return viewVisibility;
            }
            private set
            {
                viewVisibility = value;
                NotifyPropertyChanged(() => ViewVisibility);
            }
        }

        public IEnumerable<Weapon> Weapons
        {
            get
            {
                return weapons;
            }
            private set
            {
                weapons = value;
                NotifyPropertyChanged(() => Weapons);
            }
        }

        public Weapon SelectedWeapon
        {
            get
            {
                return selectedWeapon;
            }
            set
            {
                selectedWeapon = value;
                NotifyPropertyChanged(() => SelectedWeapon);
            }
        }

        public string FilterText
        {
            get
            {
                return filterText;
            }
            set
            {
                filterText = value;
                NotifyPropertyChanged(() => FilterText);
                UpdateFilterText();
            }
        }

        public DelegateCommand<object> SelectWeaponCommand { get; private set; }

        public DelegateCommand<object> CancelSelectWeaponCommand { get; private set; }

        public DelegateCommand<object> KeyDownCommand { get; private set; }

        public DelegateCommand<object> ClearFilterCommand { get; private set; }

        public void Show(Action<Weapon> selectedAction)
        {
            ViewVisibility = Visibility.Visible;
            this.selectedAction = selectedAction;
        }

        #endregion

        #region Private methods

        private void OnSelectWeaponCommand(object parameter)
        {
            ViewVisibility = Visibility.Collapsed;
            if (selectedAction != null)
            {
                selectedAction(SelectedWeapon);
            }
        }

        private void OnCancelSelectWeaponCommand(object parameter)
        {
            ViewVisibility = Visibility.Collapsed;
            if (selectedAction != null)
            {
                selectedAction(null);
            }
        }

        private void OnKeyDownCommand(object parameter)
        {
            var args = (KeyDownArgs)parameter;

            switch (args.Settings.Key)
            {
                case Key.Enter:
                    {
                        SelectWeaponCommand.Execute(null);
                    }
                    break;
                case Key.Escape:
                    {
                        CancelSelectWeaponCommand.Execute(null);
                    }
                    break;
            }
        }

        private void OnClearFilterCommand(object parameter)
        {
            var args = (KeyDownArgs)parameter;

            switch (args.Settings.Key)
            {
                case Key.Escape:
                    FilterText = String.Empty;
                    break;
            }
        }

        private void UpdateFilterText()
        {
            var collectionView = CollectionViewSource.GetDefaultView(Weapons);
            if (collectionView != null)
            {
                collectionView.Filter = (w) =>
                {
                    var weapon = (Weapon)w;
                    return weapon.Name.Contains(FilterText);
                };
            }
        }

        #endregion

        #region Private fields

        private Visibility viewVisibility;
        private IEnumerable<Weapon> weapons;
        private Weapon selectedWeapon;
        private string filterText;

        private Action<Weapon> selectedAction;

        #endregion
    }
}
